﻿using Furion.DataValidation;
using Furion.FriendlyException;
using Furion.UnifyResult;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;

namespace net8.Filter
{
    /// <summary>
    /// 统一结果格式化提供器
    /// </summary>
    [UnifyModel(typeof(UnifyFormat<>))]
    public class UnifyResultFormatProvider : IUnifyResultProvider
    {
        //JsonSerializerOptions Json = AppConfig.ServiceProvider.GetService<IOptions<JsonOptions>>().Value.JsonSerializerOptions;
        public IActionResult OnException(ExceptionContext context, ExceptionMetadata metadata)
        {
            return UnifyFormat(3, "程序发生异常", metadata.Errors);
        }

        public async Task OnResponseStatusCodes(HttpContext context, int statusCode, UnifyResultSettingsOptions unifyResultSettings = null)
        {
            string msg = "";
            switch (statusCode)
            {
                // 处理 401 状态码
                case StatusCodes.Status401Unauthorized:
                    msg = "授权失败";
                    break;
                // 处理 403 状态码
                case StatusCodes.Status403Forbidden:
                    msg = "禁止访问";
                    break;
                default: break;
            }

            await context.Response.WriteAsJsonAsync(new JsonResult(new
            {
                Status = 3,
                Msg = msg
            }));
        }

        public IActionResult OnSucceeded(ActionExecutedContext context, object data)
        {
            return UnifyFormat(1, "成功", data);
        }

        public IActionResult OnValidateFailed(ActionExecutingContext context, ValidationMetadata metadata)
        {
            var modelState = metadata.ModelState;
            var error = modelState.Where(u => modelState[u.Key].ValidationState == ModelValidationState.Invalid)
                        .ToDictionary(u => GetFirstUpper(u.Key), u => string.Join(",", modelState[u.Key].Errors.Select(c => c.ErrorMessage)));
            return UnifyFormat(2, "提交参数验证错误", error);
        }

        private IActionResult UnifyFormat<T>(int status, string msg, T data)
        {
            return new JsonResult(new
            {
                Status = status,
                Msg = msg,
                Data = data
            });
        }

        private string GetFirstUpper(string str)
        {
            return str[..1].ToLower() + str[1..];
        }
    }

    public class UnifyFormat<T>
    {
        /// <summary>
        /// 状态 1成功 2模型错误 3失败
        /// </summary>
        public int State { get; set; }

        public string Message { get; set; }

        public T Data { get; set; }
    }
}
